package dou.net.socket;

import dou.utils.UnsignedUtil;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;

/**
 * 实现了套接字解包的功能，包长度使用无符号 32 位整数
 * @author wizardc
 */
public class SimplePacketBuffer implements IPacketBuffer
{
    /**
     * 记录数据长度的协议头对象
     */
    protected ByteBuffer _headerBuffer;

    /**
     * 记录数据长度
     */
    protected long _dataLength;

    /**
     * 记录协议数据的对象
     */
    protected ByteBuffer _dataBuffer;

    /**
     * 创建一个 FlashPacketBuffer 对象
     */
    public SimplePacketBuffer()
    {
        _headerBuffer = ByteBuffer.allocate(4);
    }

    @Override
    public int readFrom(ReadableByteChannel channel) throws IOException, InvalidProtocolException
    {
        int length = 0;
        if(_dataBuffer == null)
        {
            length += readHeader(channel);
        }
        if(_dataBuffer != null)
        {
            length += readBody(channel);
        }
        return length;
    }

    private int readHeader(ReadableByteChannel channel) throws IOException
    {
        int length = channel.read(_headerBuffer);
        if(length != -1 && _headerBuffer.remaining() == 0)
        {
            _dataLength = UnsignedUtil.readUnsignedInt(_headerBuffer.array());
            if(_dataLength > 0)
            {
                _dataBuffer = ByteBuffer.allocate((int) _dataLength);
            }
        }
        return length;
    }

    private int readBody(ReadableByteChannel channel) throws IOException
    {
        return channel.read(_dataBuffer);
    }

    @Override
    public int remaining()
    {
        return _dataBuffer == null ? _headerBuffer.remaining() : _dataBuffer.remaining();
    }

    @Override
    public ByteBuffer toByteBuffer()
    {
        ByteBuffer byteBuffer = _dataBuffer.duplicate();
        byteBuffer.position(0);
        return byteBuffer;
    }
}
